package MAIN;

import java.util.Scanner;
//笔试强训第32天
//选择题
/*处于运行状态的操作系统程序就是进程，放在主存中运行，而寄存器中容量有限，只是加载cpu执行代码需
要的数据（容主存加载到寄存器），辅存：进程挂起状态，进程就会保存在辅存中*/
/*在系统中设置磁盘缓冲区的主要目的是见扫磁盘IO次数，cpu执行速度比磁盘io速度要快很多，为了提高效率
* 经常访问的磁盘数据，可以使用磁盘缓存来提高io速度（减少寻道的次数）*/
/*进程间通信的其中一种方式，信号量：p（wait）信号量 - 1，v（signal）信号量 + 1，当信号量是
正数的时候，此时进程还可以继续执行的，如果信号量是负数，此时进程就需要等待，所以执行P（wait）操作
不一定让进程从执行态变为就绪态*/
/*而当高优先级的进程抢占了低优先级的进程执行，此时低优先级的进程的时间片就提前结束，这个进程就会从
* 执行态变为就绪态*/
/*现代操作系统种采用缓冲技术的主要目的是提高cpu和设备之间的并行程度：就是cpu和磁盘中间有了缓冲区之后，
* 如果缓冲区中没有数据，此时cpu就可以去执行一些其他的任务，同时，磁盘还可以往缓冲区中写数据，等有了数据
* 然后再通知cpu来到缓冲区去读数据，此时cpu和磁盘就是并行的。*/
/*进程如果是运行状态就是在内存中，如果是挂起状态就是在外存中，而程序就是一个可执行文件，就在外存中*/
/*一个进程进行io操作是阻塞状态的，当io操作完成之后，就从阻塞状态唤醒起来转换为就绪态，就绪态等到时间片
* 调度到了之后，再转变成和运行态*/
/*OPT：最佳页面替换算法：预测哪个页面出现的最晚，就替换哪个页面。 LRU：最近最少使用页面置换算法，也就是
* 首先淘汰最长时间未被使用的页面。  MFU：最常使用算法，替换最常使用的页面  LFU：最近最不常使用的页面置换
* 算法，淘汰一定时期内被访问次数最少的页面。*/
/*互斥：一个公共资源同一时刻只能被一个进程或者线程使用，多个进程或多个线程不能同时使用公共资源
* 同步：两个或两个以上的进程或线程在运行的过程中协同步调，按预定的先后顺序运行，比如A任务的运行依赖于B任务产生的数据
* 显然，同步是一种更为复杂的互斥，而互斥是一种特殊的同步。  而并发的进程之间可能是同步的也可能是互斥的，是根据程序的
* 需求来决定的*/
/*一次IO操作的结束，是一个进程可能由阻塞态（睡眠状态）变成就绪态，不能直接变为执行态，是先变成就绪态，然后根据操作
* 系统的时间片轮转调度到了之后，这个进程才会由就绪态变成执行态*/
public class Main32 {
    //解法2
    public static void main(String[] args) {
        int border = -1;
        long[] ans = new long[100000];
        ans[0] = 1;
        ans[1] = 2;
        for (int i = 2; i < 100000; i++) {
            long next = ans[i-1] + ans[i-2];
            if (border == -1 && next >= 100000) {
                //从border这一项开始，后面的数就都是6位数或者大于6位数的了
                border = i + 1;
            }
            ans[i] = next % 1000000;
        }

        Scanner scan = new Scanner(System.in);
        while (scan.hasNextInt()) {
            int n = scan.nextInt();
            long f = ans[n-1];
            if (n < border) {
                //如果某一项不足6位，直接输出
                System.out.printf("%d\n", f);
            }else {
                //如果某一项超过6位，此时输出最后6位即可
                System.out.printf("%06d\n", f);
            }
        }
    }
    //斐波那契凤尾(数字可能会很大，如果某一项超过6位数，只输出最后6位)
    static int[] fib = new int[100001];
    public static void main2(String[] args) {
        Scanner scan = new Scanner(System.in);
        while (scan.hasNextInt()) {
            int n = scan.nextInt();//第几项
            //这里题目说的第一项是1，第二项是2，对应到数组中正好就是前两项都是1，后边就累加就行
            fib[0] = 1;
            fib[1] = 1;
            System.out.printf((n < 25 ?"%d\n" : "%06d\n"), getFibonacci(n));
        }
    }

    private static int getFibonacci(int n) {
        if (fib[2] == 0) {
            for (int i = 2; i < 100001; i++) {
                //只需要保留最后6位，
                fib[i] = (fib[i-1] + fib[i-2]) % 1000000;
            }
        }
        return fib[n];
    }


    public static boolean isPrime(int month) {
        //判断月份是否为素数
        return month == 2 || month == 3 || month == 5 || month == 7 || month == 11;
    }
    private static final int[] DAYS = {31,28,31,30,31,30,31,31,30,31,30,31};
    public static boolean isLeapYear(int year) {
        //判断是否为闰年
        if (year % 4 == 0 && year % 100 != 0 || year % 400 == 0) {
            return true;
        }
        return false;
    }
    //计算一整年的收入
    private static int profitOfYear(int year) {
        return 2*31 + 1 * 31 + 1 * 28 + 2 * 30 + 1 * 31 + 2 * 30 +
                1 * 31 + 2 * 31 + 2 * 30 + 2 * 31 + 1 * 30 + 2 * 31 +
                (isLeapYear(year) ? 1 : 0);
    }
    //计算不到一年的收入
    private static int profitOfThisYear(int year, int month, int day) {
        //计算当个月（不到一个月）的收入
        int profit = 0;
        if (!isPrime(month)) {
            profit = day * 2;//不是素数月份的收入
        }else {
            profit = day;
        }
        //计算当年当月的前几个月的收入
        while (--month > 0) {
            switch (month) {
                case 1: case 8: case 10: case 12:
                    profit += 62;
                    break;
                case 3: case 5: case 7:
                    profit += 31;
                    break;
                case 4: case 6: case 9:
                    profit += 60;
                    break;
                case 11:
                    profit += 30;
                    break;
                default: //case 2
                    profit += (28 + (isLeapYear(year) ? 1 : 0));
                    break;
            }
        }
        return profit;
    }
    public static void main1(String[] args) {
        int year1, month1, day1, year2, month2, day2;
        int profit = 0;
        Scanner scan = new Scanner(System.in);
        while (scan.hasNextInt()) {
            year1 = scan.nextInt();
            month1 = scan.nextInt();
            day1 = scan.nextInt();
            year2 = scan.nextInt();
            month2 = scan.nextInt();
            day2 = scan.nextInt();
            //例如：从1993年 5 月 7 日开始
            //计算1993年的全年收益 - 从1993年1月1日到1993年5月6日的收益 --> 就是从起始日期开始（算当天）到年底的收益
            /*因为起始的那天的收益也是需要算进去的*/
            /*也就是计算的是起始年份起始日期到年底的收益*/
            profit = profitOfYear(year1) - profitOfThisYear(year1, month1, day1 - 1);
            //计算终止年的不到一年的收入
            profit += profitOfThisYear(year2, month2, day2);

            //起始年份和终止年份是相等的
            if (year1 == year2) {
                //如：1993年5月1日 - 1993年10月5日
                profit -= profitOfYear(year1);//一定要理清这块的关系，就是减去一整年就是正确的收益
            }
            //如果起始年和终止年份不相等，此时就算中间几年的收益
            for (int i = year1 + 1; i < year2; i++) {
                profit += profitOfYear(i);
            }

            System.out.println(profit);
        }
    }
}
